//! Sandbox
//! 
//! 沙盒相当于一个Md和Td的网关加上一个时间扭曲模拟器,
//! 从数据库(Md)中获取数据, 通过时间扭曲来模拟时间扭曲TickData和Order,
//! 结果发送给核心(Td)进行撮合
//! 

#![allow(unused)]
pub mod simulate;
use eztrade_dto::{
    DataTransferObject, stage::{self, StageInfo},
    events::{SubscribeEvent, GlobalEvent, Frequency},
    Message, tick::{TickData, Orderstack}
};
use eztrade_macro::SandboxTypeImpl;
use anyhow::Result;
use chrono::{DateTime, Utc};
use tokio::sync::broadcast::{self, Receiver, Sender};

use std::sync::{OnceLock, Arc, RwLock, LazyLock};
use std::collections::{HashMap, VecDeque, HashSet};
use tokio::time::{Duration, sleep};
use serde::{Deserialize, Serialize};

/// Enum for Sandbox Type
/// 沙盒类型, 用于区分不同的沙盒实现
/// 
/// 使用 SandboxTypeImpl 宏自动实现 SandboxTrait
/// 确保所有变体都必须实现 SandboxTrait
#[derive(SandboxTypeImpl)]
pub enum SandboxType {
    /// 简易沙盒
    SimpleSimulator(simulate::SimpleSandboxSimulator),
    // 示例：当添加新的 Sandbox 类型时，必须确保它实现了 SandboxTrait
    // AdvancedSimulator(simulate::AdvancedSandboxSimulator),
}

/// 可变全局沙盒映射 - 从stage_id到SimpleSandboxSimulator的映射
static SANDBOX_MAP: LazyLock<RwLock<HashMap<u64, Arc<SandboxType>>>> = LazyLock::new(|| RwLock::new(HashMap::new()));

/// 获取或初始化沙盒实例
pub fn create_sandbox(stage_id: u64, stage_info: StageInfo) -> Result<Arc<SandboxType>> {
    let mut sandbox_map = SANDBOX_MAP.write().unwrap();    
    // 创建新的沙盒实例 - 使用 SandboxTrait::new 方法
    // 宏会自动分发到正确的实现
    let sandbox = Arc::new(SandboxType::new(stage_info));
    sandbox_map.insert(stage_id, sandbox.clone());
    
    Ok(sandbox)
}

/// 获取沙盒实例
pub fn get_sandbox(stage_id: u64) -> Option<Arc<SandboxType>> {
    let sandbox_map = SANDBOX_MAP.read().unwrap();
    sandbox_map.get(&stage_id).cloned()
}

/// 列出所有沙盒对应的 StageInfo
pub fn list_stage_infos() -> Vec<StageInfo> {
    let sandbox_map = SANDBOX_MAP.read().unwrap();
    sandbox_map.values().map(|sb| sb.get_stage_info()).collect()
}

/// TimeWarp Trait
/// 
/// 时间扭曲，用于通过真实时间和倍率来计算模拟时间
pub trait TimeWarpTrait {
    /// 对齐当前时间到指定的开始时间
    fn align_with(self, start_time: DateTime<Utc>) -> Self;
    /// 设置时间倍率
    fn scale_with(self, scale: f64) -> Self;
    /// 获取现在的模拟时间
    fn get_simulated_time(&self) -> DateTime<Utc>;
    /// 获取模拟时间的经过时间
    fn get_simulated_elapsed(&self) -> chrono::Duration;
}

/// Sandbox Trait
/// 
/// 沙盒环境的基本特征, 可对接不同的RX/TX,
/// 需要实现基本方法
pub trait SandboxTrait{
    fn new(stage: stage::StageInfo) -> Self; // spawn
    fn get_stage_phase(&self) -> stage::StagePhase;
    fn get_stage_info(&self) -> stage::StageInfo;
    fn start(&self) -> Result<()>;
    fn subscribe(&self, client_id: u64, subscribe: SubscribeEvent) -> Result<()>;
    fn unsubscribe(&self, client_id: u64, subscribe: SubscribeEvent) -> Result<()>;
    fn subscribe_global(&self, subscribe: GlobalEvent) -> Result<()>;
    fn unsubscribe_global(&self, subscribe: GlobalEvent) -> Result<()>;
    fn get_receiver(&self, client_id: u64) -> Result<Receiver<Message>>; // 获取接收器(接收行情以及订阅信息)
    fn process_message(&self, client_id: u64, message: Message) -> Option<(Message)>; // 处理来自客户端的消息, 并返回相关信息
}
